#ifndef POPUP_CLIENT_QTHREAD_H
#define POPUP_CLIENT_QTHREAD_H

#include <QThread>
#include <QMutex>
#include <PopupClientUI.hpp>

struct PopupClientThread : public QThread, public Popup::ClientUI
{
  Q_OBJECT

public:
  
  PopupClientThread()
    : m_client(Popup::Client::newClient(this)),
      m_restartScheduled(false), m_tryToConnect(false) {}
  
  virtual void run();

  //------------------------------------------
  // Implementation of PopupClientUI interface
  //------------------------------------------

  virtual void onFileTransferUpdate(const Popup::FileTransfer &);
  virtual void onMessageReceived(const Popup::UserMessage &);
  virtual void onMessageSent(const Popup::UserMessage &);
  virtual void onMessageReactionReceived(const Popup::RateUserMessage &);
  virtual void onOpinionRequested(const Popup::Canvass&);
  virtual void onVoteReceived(const Popup::Vote & p_vote);
  virtual void onInvitationReceived(const Popup::ThreadInvitation & p_invitation);
  virtual void onConnectionUpdate(bool p_connected,
                                  const Popup::User & p_myself,
                                  Popup::SessionID p_sessionID);
  virtual void onUserUpdate(const Popup::User & p_user,
                            unsigned short p_updateMask,
                            bool p_isNewUser);
  virtual void onUserStatisticsUpdate(Popup::UserID p_userID,
                                      Popup::UserStatistics & p_stats);
  virtual std::string getTemporaryDir();
  virtual std::string getResourceDir();

public slots:
  void slot_setConnectionParams(const QString & p_login,
                                const QString & p_password,
                                const QString & p_server,
                                int p_port, bool p_register);
  void slot_sendMessage(Popup::UserMessage *p_message);
  void slot_sendMessageReaction(Popup::RateUserMessage *p_reaction);
  void slot_restartClient();
  void slot_disconnect();
  void slot_localUserUpdated(const Popup::User *p_me,
                             unsigned short p_updateMask);
  void slot_submitCanvass(Popup::Canvass *p_canvass);
  void slot_sendVote(Popup::Vote *p_vote);
  void slot_sendInvitation(Popup::ThreadInvitation *p_invitation);

signals:
  void signal_badConnectionParams(Popup::ConnectionEcode p_ecode);
  void signal_onConnectionUpdate(bool p_connected, Popup::User p_myself,
                                 Popup::SessionID p_sessionID);
  void signal_updateUser(Popup::User p_user, unsigned short p_updateMask,
                         bool p_isNewUser);
  void signal_messageReceived(Popup::UserMessage p_message);
  void signal_messageSent(Popup::UserMessage p_message);
  void signal_messageReactionReceived(Popup::RateUserMessage p_reaction);
  void signal_onVoteReceived(Popup::Vote);
  void signal_onInvitationReceived(Popup::ThreadInvitation);
  void signal_onOpinionRequested(Popup::Canvass);
  void signal_updateFileTransferProgress(Popup::FileTransfer p_tranfer);
  void signal_updateUserStatistics(Popup::UserID p_userID,
                                   Popup::UserStatistics p_stats);

private:
  Popup::Client *m_client;
  bool m_restartScheduled;
  bool m_tryToConnect;
  std::string m_login;
  std::string m_password;
  std::string m_server;
  unsigned short m_port;
  bool m_register;
};

#endif
